【面试题】如何避免使用过多的 if else? 您所在的位置:网站首页 elseif和else if区别 【面试题】如何避免使用过多的 if else?

【面试题】如何避免使用过多的 if else?

2023-05-10 19:18| 来源: 网络整理| 查看: 265

【面试题】如何避免使用过多的 if else?_复杂度

一、引言

相信大家听说过回调地狱——回调函数层层嵌套,极大降低代码可读性。其实,if-else层层嵌套,如下图所示,也会形成类似回调地狱的情况。

【面试题】如何避免使用过多的 if else?_前端_02

当业务比较复杂,判断条件比较多,项目进度比较赶时,特别容易使用过多if-else。其弊端挺多的,如代码可读性差、代码混乱、复杂度高、影响开发效率、维护成本高等。

因此,我们在日常编码时,有必要采取一些措施避免这些问题。本文的初衷不是建议大家完全不用if-else,而是希望我们能够在学会更多解决方案后更优雅地编码。

二、8种if-else的优化/替代方案1. 使用排非策略:!、!!

逻辑非(logic NOT),是逻辑运算中的一种,就是指本来值的反值。

当你想这么写时……

1、判断是否为空 if(value === null || value === NaN || value === 0 || value === ''|| value === undefined ) { …… } 2、判断是否数组是否含有符合某条件的元素 const name = arr.find(item => item.status === 'error')?.name; if(name !== undefined && name !== ''){ …… } 复制代码

不妨尝试这么写:

1、判断是否为空 if(!value){……} 2、判断是否数组是否含有符合某条件的元素 if(!!arr.find(item => item.status === 'error')?.name){……} 复制代码2. 使用条件(三元)运算符: c ? t : f

三元运算符: condition ? exprIfTrue : exprIfFalse; 如果条件为真值,则执行冒号(:)前的表达式;若条件为假值,则执行最后的表达式。

当你想这么写时……

let beverage = ''; if(age > 20){ beverage = 'beer'; } else { beverage = 'juice'; } 复制代码

不妨尝试这么写:

const beverage = age > 20 ? 'beer' : 'juice'; 复制代码

tips: 建议只用一层三元运算符,多层嵌套可读性差。

3. 使用短路运算符:&&、 ||&&||

当你想这么写时……

if (isOnline){ makeReservation(user); } 复制代码

不妨尝试这么写:

isOnline && makeReservation(user); 复制代码4. 使用 switch 语句

当你想这么写时……

let result; if (type === 'add'){ result = a + b; } elseif(type === 'subtract'){ result = a - b; } elseif(type === 'multiply'){ result = a * b; } elseif(type === 'divide'){ result = a / b; } else { console.log('Calculation is not recognized'); } 复制代码

不妨尝试这么写:

let result; switch (type) { case'add': result = a + b; break; case'subtract': result = a - b; break; case'multiply': result = a * b; break; case'divide': result = a / b; break; default: console.log('Calculation is not recognized'); } 复制代码

个人认为,对于这类比较简单的判断,用switch语句虽然不会减少代码量,但是会更清晰喔。

5. 定义相关函数拆分逻辑,简化代码

当你想这么写时……

functionitemDropped(item, location) { if (!item) { returnfalse; } elseif (outOfBounds(location) { var error = outOfBounds; server.notify(item, error); items.resetAll(); returnfalse; } else { animateCanvas(); server.notify(item, location); returntrue; } } 复制代码

不妨尝试这么写:

// 定义dropOut和dropIn, 拆分逻辑并提高代码可读性functionitemDropped(item, location) { const dropOut = function () { server.notify(item, outOfBounds); items.resetAll(); returnfalse; }; const dropIn = function () { animateCanvas(); server.notify(item, location); returntrue; }; return !!item && (outOfBounds(location) ? dropOut() : dropIn()); } 复制代码

细心的朋友会发现,在这个例子中,同时使用了前文提及的优化方案。这说明我们在编码时可以根据实际情况混合使用多种解决方案。

6. 将函数定义为对象,通过穷举查找对应的处理方法① 定义普通对象

对于方案3的例子,不妨尝试这么写:

functioncalculate(action, num1, num2) { const actions = { add: (a, b) => a + b, subtract: (a, b) => a - b, multiply: (a, b) => a * b, divide: (a, b) => a / b, }; return actions[action]?.(num1, num2) ?? "Calculation is not recognized"; } 复制代码② 定义 Map 对象

普通对象的键需要是字符串,而 Map

let statusMap = newMap([ [ { role: "打工人", status: "1" }, () => { /*一些操作*/}, ], [ { role: "打工人", status: "2" }, () => { /*一些操作*/}, ], [ { role: "老板娘", status: "1" }, () => { /*一些操作*/}, ], ]); let getStatus = function (role, status) { statusMap.forEach((value, key) => { if (JSON.stringify(key) === JSON.stringify({ role, status })) { value(); } }); }; getStatus("打工人", "1"); // 一些操作复制代码

tips: JSON.stringify()可用于深比较/深拷贝。

7. 使用责任链模式

责任链模式:将整个处理的逻辑改写成一条责任传递链,请求在这条链上传递,直到有一个对象处理这个请求。

例如 JS 中的事件冒泡。

简单来说,事件冒泡就是在一个对象上绑定事件,如果定义了事件的处理程序,就会调用处理程序。相反没有定义的话,这个事件会向对象的父级传播,直到事件被执行,最后到达最外层,document对象上。

【面试题】如何避免使用过多的 if else?_Powered by 金山文档_03

这意味着,在这种模式下,总会有程序处理该事件。

再举个🌰,当你想这么写时……

functiondemo (a, b, c) { if (f(a, b, c)) { if (g(a, b, c)) { // ... } // ...elseif (h(a, b, c)) { // ... } // ... } elseif (j(a, b, c)) { // ... } elseif (k(a, b, c)) { // ... } } 复制代码

不妨参考这种写法:

const rules = [ { match: function (a, b, c) { /* ... */ }, action: function (a, b, c) { /* ... */ } }, { match: function (a, b, c) { /* ... */ }, action: function (a, b, c) { /* ... */ } }, { match: function (a, b, c) { /* ... */ }, action: function (a, b, c) { /* ... */ } } // ... ] // 每个职责一旦匹配,原函数就会直接返回。functiondemo (a, b, c) { for (let i = 0; i < rules.length; i++) { if (rules[i].match(a, b, c)) { return rules[i].action(a, b, c) } } } 复制代码

引申话题——如何降低if else代码的复杂度? 相关文章阅读: 如何无痛降低 if else 面条代码复杂度

三、小结

本文粗略介绍了8种优化/替代if-else的方法,希望能给你日常编码带来一些启示😄。

正如开头所说,我们的目的不是消灭代码中的if-else,而是让我们在学会更多解决方案的基础上,根据实际情况选择更优的编码方式。因此,当你发现自己的代码里面存在特别多的if-else或当你想用if-else时,不妨停下来思考一下——如何能写得更优雅、更方便日后维护呢。

【面试题】如何避免使用过多的 if else?_开发语言_04



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有